<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Choosing a Reactor and GUI Toolkit Integration</title>
  </head>
  <body>
    <h1>Choosing a Reactor and GUI Toolkit Integration</h1>

    <h2>Overview</h2>

    <p>Twisted provides a variety of implementations of the <code
    class="API">twisted.internet.reactor</code>.  The specialized
    implementations are suited for different purposes and are
    designed to integrate better with particular platforms.</p>

    <p>The <a href="#epoll">epoll()-based reactor</a> is Twisted's default on
    Linux. Other platforms use <a href="#poll">poll()</a>, or the most
    cross-platform reactor, <a href="#select">select()</a>.</p>

    <p>Platform-specific reactor implementations exist for:</p>

    <ul>
      <li><a href="#poll">Poll for Linux</a></li>
      <li><a href="#epoll">Epoll for Linux 2.6</a></li>
      <li><a href="#win32_wfmo">WaitForMultipleObjects (WFMO) for Win32</a></li>
      <li><a href="#win32_iocp">Input/Output Completion Port (IOCP) for Win32</a></li>
      <li><a href="#kqueue">KQueue for FreeBSD and Mac OS X</a></li>
      <li><a href="#cfreactor">CoreFoundation for Mac OS X</a></li>
    </ul>

    <p>The remaining custom reactor implementations provide support
    for integrating with the native event loops of various graphical
    toolkits.  This lets your Twisted application use all of the
    usual Twisted APIs while still being a graphical application.</p>

    <p>Twisted currently integrates with the following graphical
    toolkits:</p>

    <ul>
      <li><a href="#gtk">GTK+ 2.0</a></li>
      <li><a href="#gtk3">GTK+ 3.0 and GObject Introspection</a></li>
      <li><a href="#tkinter">Tkinter</a></li>
      <li><a href="#wxpython">wxPython</a></li>
      <li><a href="#win32_wfmo">Win32</a></li>
      <li><a href="#cfreactor">CoreFoundation</a></li>
      <li><a href="#pyui">PyUI</a></li>
    </ul>

    <p>When using applications that are runnable using <code>twistd</code>, e.g.
       TACs or plugins, there is no need to choose a reactor explicitly, since
       this can be chosen using <code>twistd</code>'s -r option.</p>

    <p>In all cases, the event loop is started by calling <code
    class="python">reactor.run()</code>. In all cases, the event loop
    should be stopped with <code
    class="python">reactor.stop()</code>.</p>

    <p><strong>IMPORTANT:</strong> installing a reactor should be the first thing
    done in the app, since any code that does
    <code class="python">from twisted.internet import reactor</code> will automatically
    install the default reactor if the code hasn't already installed one.</p>

    <h2>Reactor Functionality</h2>

    <table cellpadding="7" cellspacing="0" border="1" title="Summary of reactor features">
    <tr><td></td><th>Status</th><th>TCP</th><th>SSL</th><th>UDP</th><th>Threading</th><th>Processes</th><th>Scheduling</th><th>Platforms</th></tr>
    <tr><th>select()</th><td>Stable</td><td>Y</td><td>Y</td><td>Y</td><td>Y</td><td>Y</td><td>Y</td><td>Unix, Win32</td></tr>
    <tr><th>poll</th><td>Stable</td><td>Y</td><td>Y</td><td>Y</td><td>Y</td><td>Y</td><td>Y</td><td>Unix</td></tr>
    <tr><th>WaitForMultipleObjects (WFMO) for Win32</th><td>Experimental</td><td>Y</td><td>Y</td><td>Y</td><td>Y</td><td>Y</td><td>Y</td><td>Win32</td></tr>
    <tr><th>Input/Output Completion Port (IOCP) for Win32</th><td>Experimental</td><td>Y</td><td>Y</td><td>Y</td><td>Y</td><td>Y</td><td>Y</td><td>Win32</td></tr>
    <tr><th>CoreFoundation</th><td>Unmaintained</td><td>Y</td><td>Y</td><td>Y</td><td>Y</td><td>Y</td><td>Y</td><td>Mac OS X</td></tr>
    <tr><th>epoll</th><td>Stable</td><td>Y</td><td>Y</td><td>Y</td><td>Y</td><td>Y</td><td>Y</td><td>Linux 2.6</td></tr>
    <tr><th>GTK+</th><td>Stable</td><td>Y</td><td>Y</td><td>Y</td><td>Y</td><td>Y</td><td>Y</td><td>Unix, Win32</td></tr>
    <tr><th>wx</th><td>Experimental</td><td>Y</td><td>Y</td><td>Y</td><td>Y</td><td>Y</td><td>Y</td><td>Unix, Win32</td></tr>
    <tr><th>kqueue</th><td>Experimental</td><td>Y</td><td>Y</td><td>Y</td><td>Y</td><td>Y</td><td>Y</td><td>FreeBSD</td></tr>
    </table>

    <h2>General Purpose Reactors</h2>

    <h3>Select()-based Reactor</h3><a name="select" />

    <p>The <code>select</code> reactor is the default on platforms that don't
    provide a better alternative that covers all use cases. If
    the <code>select</code> reactor is desired, it may be installed via:</p>

<pre class="python">
from twisted.internet import selectreactor
selectreactor.install()

from twisted.internet import reactor
</pre>

    <h2>Platform-Specific Reactors</h2>

    <h3>Poll-based Reactor</h3><a name="poll" />

    <p>The PollReactor will work on any platform that provides <code
    class="python">select.poll</code>.  With larger numbers of connected
    sockets, it may provide for better performance than the SelectReactor.</p>

<pre class="python">
from twisted.internet import pollreactor
pollreactor.install()

from twisted.internet import reactor
</pre>

    <h3>KQueue</h3><a name="kqueue" />

    <p>The KQueue Reactor allows Twisted to use FreeBSD's kqueue mechanism for
       event scheduling. See instructions in the <code class="API"
       >twisted.internet.kqreactor</code>'s
       docstring for installation notes.</p>

<pre class="python">
from twisted.internet import kqreactor
kqreactor.install()

from twisted.internet import reactor
</pre>


   <h3>WaitForMultipleObjects (WFMO) for Win32</h3><a name="win32_wfmo" />

    <p>The Win32 reactor is not yet complete and has various limitations
    and issues that need to be addressed.  The reactor supports GUI integration
    with the win32gui module, so it can be used for native Win32 GUI applications.
    </p>

<pre class="python">
from twisted.internet import win32eventreactor
win32eventreactor.install()

from twisted.internet import reactor
</pre>

   <h3>Input/Output Completion Port (IOCP) for Win32</h3><a name="win32_iocp" />

    <p>
    Windows provides a fast, scalable event notification system known as IO
    Completion Ports, or IOCP for short.  Twisted includes a reactor based
    on IOCP which is nearly complete.
    </p>

<pre class="python">
from twisted.internet import iocpreactor
iocpreactor.install()

from twisted.internet import reactor
</pre>

    <h3>Epoll-based Reactor</h3><a name="epoll" />

    <p>The EPollReactor will work on any platform that provides
    <code class="python">epoll</code>, today only Linux 2.6 and over. The
    implementation of the epoll reactor currently uses the Level Triggered
    interface, which is basically like poll() but scales much better.</p>

<pre class="python">
from twisted.internet import epollreactor
epollreactor.install()

from twisted.internet import reactor
</pre>

    <h2>GUI Integration Reactors</h2>

    <h3>GTK+</h3><a name="gtk" />

    <p>Twisted integrates with <a href="http://www.pygtk.org/">PyGTK</a> version
    2.0 using the <code>gtk2reactor</code>. An example Twisted application that
    uses GTK+ can be found
    in <code class="py-filename">doc/core/examples/pbgtk2.py</code>.</p>

    <p>GTK-2.0 split the event loop out of the GUI toolkit and into a separate
    module called <q>glib</q>. To run an application using the glib event loop,
    use the <code>glib2reactor</code>. This will be slightly faster
    than <code>gtk2reactor</code> (and does not require a working X display),
    but cannot be used to run GUI applications.</p>

<pre class="python">
from twisted.internet import gtk2reactor # for gtk-2.0
gtk2reactor.install()

from twisted.internet import reactor
</pre>

<pre class="python">
from twisted.internet import glib2reactor # for non-GUI apps
glib2reactor.install()

from twisted.internet import reactor
</pre>

    <h3>GTK+ 3.0 and GObject Introspection</h3><a name="gtk3" />

    <p>Twisted integrates with <a href="http://gtk.org">GTK+ 3</a> and GObject
    through <a href="http://live.gnome.org/PyGObject">PyGObject's</a>
    introspection using the <code>gtk3reactor</code>
    and <code>gireactor</code> reactors.</p>

<pre class="python">
from twisted.internet import gtk3reactor
gtk3reactor.install()

from twisted.internet import reactor
</pre>

<pre class="python">
from twisted.internet import gireactor # for non-GUI apps
gireactor.install()

from twisted.internet import reactor
</pre>

    <p>GLib 3.0 introduces the concept of <code>GApplication</code>, a class
    that handles application uniqueness in a cross-platform way and provides
    its own main loop. Its counterpart <code>GtkApplication</code> also
    handles application lifetime with respect to open windows. Twisted
    supports registering these objects with the event loop, which should be
    done before running the reactor:</p>

<pre class="python">
from twisted.internet import gtk3reactor
gtk3reactor.install()

from gi.repository import Gtk
app = Gtk.Application(...)

from twisted import reactor
reactor.registerGApplication(app)
reactor.run()
</pre>

    <h3>wxPython</h3><a name="wxpython" />

    <p>Twisted currently supports two methods of integrating
    wxPython. Unfortunately, neither method will work on all wxPython
    platforms (such as GTK2 or Windows). It seems that the only
    portable way to integrate with wxPython is to run it in a separate
    thread. One of these methods may be sufficient if your wx app is
    limited to a single platform.</p>

    <p>As with <a href="#tkinter">Tkinter</a>, the support for integrating
    Twisted with a <a href="http://www.wxpython.org">wxPython</a>
    application uses specialized support code rather than a simple reactor.</p>

<pre class="python">
from wxPython.wx import *
from twisted.internet import wxsupport, reactor

myWxAppInstance = wxApp(0)
wxsupport.install(myWxAppInstance)
</pre>

    <p>However, this has issues when running on Windows, so Twisted now
    comes with alternative wxPython support using a reactor. Using
    this method is probably better. Initialization is done in two
    stages. In the first, the reactor is installed:</p>

<pre class="python">
from twisted.internet import wxreactor
wxreactor.install()

from twisted.internet import reactor
</pre>

    <p>Later, once a <code class="python">wxApp</code> instance has
    been created, but before <code class="python">reactor.run()</code>
    is called:</p>

<pre class="python">
from twisted.internet import reactor
myWxAppInstance = wxApp(0)
reactor.registerWxApp(myWxAppInstance)
</pre>

    <p>An example Twisted application that uses wxPython can be found
    in <code class="py-filename">doc/core/examples/wxdemo.py</code>.</p>

    <h3>CoreFoundation</h3><a name="cfreactor" />

    <p>Twisted integrates with <a href="http://pyobjc.sf.net/"
    >PyObjC</a> version 1.0. Sample applications using Cocoa and Twisted
    are available in the examples directory under
    <code>doc/core/examples/threadedselect/Cocoa</code>.</p>

<pre class="python">
from twisted.internet import cfreactor
cfreactor.install()

from twisted.internet import reactor
</pre>

    <h2>Non-Reactor GUI Integration</h2>

    <h3>Tkinter</h3><a name="tkinter" />

    <p>The support for <a href="http://wiki.python.org/moin/TkInter"
    >Tkinter</a> doesn't use a specialized reactor.  Instead, there is
    some specialized support code:</p>

<pre class="python">
from Tkinter import *
from twisted.internet import tksupport, reactor

root = Tk()

# Install the Reactor support
tksupport.install(root)

# at this point build Tk app as usual using the root object,
# and start the program with "reactor.run()", and stop it
# with "reactor.stop()".
</pre>

    <h3>PyUI</h3><a name="pyui" />

    <p>As with <a href="#tkinter">Tkinter</a>, the support for integrating
    Twisted with a <a href="http://pyui.sourceforge.net">PyUI</a>
    application uses specialized support code rather than a simple reactor.</p>

<pre class="python">
from twisted.internet import pyuisupport, reactor

pyuisupport.install(args=(640, 480), kw={'renderer': 'gl'})
</pre>

    <p>An example Twisted application that uses PyUI can be found in <code
    class="py-filename">doc/core/examples/pyuidemo.py</code>.</p>

  </body>
</html>
